package com.fingard.dsp.bank.directbank.gdrc01;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.directbank.fngrd01.util.StringHelper;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by F on 2018/10/10.
 * 今日明细，历史明细
 */
public class GDRC01Transaction extends GDRC01Base implements ITransaction {

    /**
     * 历史明细
     * @param p_req7516
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception{
        return d7516HisTrans_A(p_req7516);
    }

    /**
     * 集团含成员单位
     * @param p_req7516
     * @return
     * @throws Exception
     */
    private RetAtsTrans d7516HisTrans_A(Req7516HisTrans p_req7516) throws Exception{
        RetAtsTrans retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
        retAtsTrans.writeStart();
        String tmpRespCode = "";
        String tmpRespInfo ="";
        try{
            //起始日期
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());
            //结束日期
            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());
            //明细按月查询，有些银行不支持跨月查询
            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            while(tmpIntDateFrom<=tmpIntDateTo && StringHelper.isNullOrEmpty(tmpRespCode)){
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //当是跨月查询时，先查询起始日期到月末日期记录，再查询月末后一天日期到结束日期记录
                if(DateHelper.compareMonth(tmpCalendarFrom,tmpCalendarTo)==-1){//起始日期月份小于结束日期月份，表示跨月
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH,tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));//获取月末日期
                }else{
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }
                int tmpNowReadStart = 1;//起始笔数
                int tmpNowReadNum = 0;//已查询笔数
                Map<String,Integer> tmpTotalNum = new HashMap<String, Integer>();
                while (tmpNowReadNum==0 || tmpNowReadNum<tmpTotalNum.get("recordCount")){
                    //开始拼接请求报文头
                    XmlTextWriter xmlTextWriter = new XmlTextWriter();
                    GDRC01Header gdrc01Header=new GDRC01Header();
                    gdrc01Header.TrsCode="B2EGroupActTrsQry";
                    gdrc01Header.ERPJnlNo=p_req7516.reqHeader.transSeqID;
                    writeCommonHeader(xmlTextWriter,gdrc01Header);
                    xmlTextWriter.writeEndElement();
                    //开始拼接请求报文体
                    XElement body = new XElement("Body","");
                    body.addChild(new XElement("AcNo",p_req7516.actNum));//账号
                    body.addChild(new XElement("BeginDate",Format.Date8Format.format(tmpCalendarFrom.getTime())));//交易起始日期yyyyMMdd
                    body.addChild(new XElement("EndDate",Format.Date8Format.format(tmpClndrStepTo.getTime())));//交易终止日期yyyyMMdd
                    body.addChild(new XElement("BeginNo",tmpNowReadStart+""));//交易起始号码
                    body.addChild(new XElement("RecordNum",getBankConfig().getValueAsString("pageSize")));//查询条数
                    xmlTextWriter.writeXElement(body);
                    xmlTextWriter.writeEndDocument();
                    //发送请求报文
                    String[] resutlt = sendToBank(xmlTextWriter.toXmlString());

                    //测试
                    //resutlt[0]="";
                    //resutlt[1]="<Message>   <Head>      <IBSReturnCode>000000</IBSReturnCode>      <IBSReturnMsg>交易成功</IBSReturnMsg>      <IBSJnlNo/>   </Head>   <Body>      <RecordCount>3</RecordCount>      <TotalCount>3</TotalCount>      <List>         <Map>            <AcNo>80020000000807809</AcNo>            <HostJnlNo>1795003</HostJnlNo>            <TransDate>20301231</TransDate>            <TransTime>090542</TransTime>            <TransType>转账收入</TransType>            <DeptId>00101</DeptId>            <DeptName>广东省农村信用社联合社清算中心</DeptName>            <Amount>0.01</Amount>            <PeerDeptId>江门农村商业银行股份有限公司营业部</PeerDeptId>            <Balance>102160.64</Balance>            <PeerAcNo>80020000000807810</PeerAcNo>            <PeerAcName>汇海成员子公司888</PeerAcName>            <Currency>CNY</Currency>            <Summary>摘要</Summary>         </Map>         <Map>            <AcNo>80020000000807809</AcNo>            <HostJnlNo>1793155</HostJnlNo>            <TransDate>20301231</TransDate>            <TransTime>085026</TransTime>            <TransType>转账支出</TransType>            <DeptId>00101</DeptId>            <DeptName>广东省农村信用社联合社清算中心</DeptName>            <Amount>-0.02</Amount>            <PeerDeptId>江门农村商业银行股份有限公司营业部</PeerDeptId>            <Balance>102160.63</Balance>            <PeerAcNo>80020000000247937</PeerAcNo>            <PeerAcName>麦德龙特卖商品市场</PeerAcName>            <Currency>CNY</Currency>            <Summary>摘要</Summary>         </Map>         <Map>            <AcNo>80020000000807809</AcNo>            <HostJnlNo>1792565</HostJnlNo>            <TransDate>20301231</TransDate>            <TransTime>084545</TransTime>            <TransType>转账支出</TransType>            <DeptId>00101</DeptId>            <DeptName>广东省农村信用社联合社清算中心</DeptName>            <Amount>-0.01</Amount>            <PeerDeptId>江门农村商业银行股份有限公司营业部</PeerDeptId>            <Balance>102160.65</Balance>            <PeerAcNo>80020000000223574</PeerAcNo>            <PeerAcName>天颂航空公司</PeerAcName>            <Currency>CNY</Currency>            <Summary>摘要</Summary>         </Map>      </List>   </Body></Message>\n";
                    //WriteBankLogStep3(resutlt[1]);

                    //处理响应报文
                    if(resutlt[0].length()==0){
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(resutlt[1].trim(),tmpSbMsg);
                        if(tmpBkReader!=null) {
                            String respCode = tmpBkReader.getFirstText("/Message/Head/IBSReturnCode");
                            String respInfo = tmpBkReader.getFirstText("/Message/Head/IBSReturnMsg");
                            //交易成功
                            if("000000".equals(respCode)){
                                String recordCount = tmpBkReader.getFirstText("/Message/Body/TotalCount");//获取总记录数
                                String totalCount = tmpBkReader.getFirstText("/Message/Body/RecordCount");//获取页面记录条数
                                if(tmpTotalNum.containsKey("recordCount")){
                                    if(tmpTotalNum.get("recordCount").intValue()!=Integer.valueOf(recordCount).intValue()){
                                        tmpRespCode ="-1";
                                        tmpRespInfo = "相同条件前后查出来的总数不一致";
                                        break;
                                    }
                                }else{
                                    if("0".equals(recordCount)){
                                        tmpRespCode ="0";
                                        tmpRespInfo = "该时间段的总明细条数为0";
                                        break;
                                    }
                                    tmpTotalNum.put("recordCount",Integer.valueOf(recordCount));//记录总条数
                                }
                                //取List/Map循环数据的值
                                int readCount =0;//设置遍历计数
                                while (tmpBkReader.read("/Message/Body/List/Map")){
                                    XElement readXElement = tmpBkReader.readedXElement;
                                    RetAtsTransDetail detail = new RetAtsTransDetail();
                                    detail.actArea=p_req7516.actArea;//账户区域
                                    detail.actNum=readXElement.getSingleTextNotNull("AcNo").trim();//银行账号
                                    detail.recAccNum=readXElement.getSingleTextNotNull("PeerAcNo").trim();//收方银行账号
                                    detail.recAccName=readXElement.getSingleTextNotNull("PeerAcName").trim();//收方账户名称
                                    detail.recAccBank=readXElement.getSingleTextNotNull("PeerDeptId").trim();//收方银行
                                    detail.tranDate=DateHelper.convertD8toD10(readXElement.getSingleTextNotNull("TransDate").trim());//交易日期
                                    String tranTime=readXElement.getSingleTextNotNull("TransTime").trim();//交易时间
                                    detail.tranTime=detail.tranDate+" "+DateHelper.getFormat8Time(tranTime);//交易时间
                                    detail.valueDate=detail.tranDate;//起息日，银行没有返回就用tranDate交易日期
                                    String amount=readXElement.getSingleTextNotNull("Amount").trim();
                                    //转入（收）为正数，转出（支）为负数
                                    if (amount.indexOf("-")>=0){//借
                                        detail.cdFlag="1";
                                        detail.tranAmt=amount.substring(1);//交易金额
                                    }else {//贷
                                        detail.cdFlag="2";
                                        detail.tranAmt=amount;//交易金额
                                    }
                                    detail.accBal=readXElement.getSingleTextNotNull("Balance").trim();//账户余额
                                    detail.postTimestamp="";//时间戳，银行没有就空
                                    detail.billType="";//单据或票据类型，银行没有就空
                                    detail.billNum="";//单据或票据号码，银行没有就空
                                    String note = readXElement.getSingleTextNotNull("Summary").trim();
                                    detail.usage=note;//摘要
                                    detail.abstr=pickupAbstr(note);//对账码
                                    detail.payCode="";//支付码
                                    detail.comment="";//备注
                                    detail.askNumber="";//支付流水号
                                    detail.reqBatchNO="";//支付批号
                                    detail.cur=convertCurToATS(readXElement.getSingleTextNotNull("Currency").trim());//币种
                                    detail.seqId="";//序列号
                                    detail.isCollection="";//是否现金池，银行没有就空
                                    detail.originator="";//柜员号
                                    detail.busType="";//新业务类型
                                    detail.urid="";//唯一明细号
                                    retAtsTrans.writeRetDetail(detail);
                                    readCount++;
                                }
                                //查询记录数和遍历数不一致
                                if(readCount!=Integer.valueOf(totalCount)){
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "统计明细有误";
                                    break;
                                }
                                tmpNowReadStart +=readCount;
                                tmpNowReadNum +=readCount;
                            }else {
                                tmpRespCode = "-1";
                                tmpRespInfo = respInfo;
                                break;
                            }
                        }else{
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpSbMsg.toString();
                            break;
                        }
                    }else{
                        tmpRespCode = "-1";
                        tmpRespInfo = resutlt[1];
                        break;
                    }
                }
                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);//月末后一天日期
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        }catch (Exception ex){
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            ex.printStackTrace();
            WriteBankLogLn("查询明细异常:"+ex);
        }
        if ("-1".equals(tmpRespCode)) {
            retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
            retAtsTrans.writeStart();//写返回ATS的统一头部信息
            retAtsTrans.writeRespCode(tmpRespCode);
            retAtsTrans.writeRespInfo(tmpRespInfo);
        }else if(retAtsTrans.getWrittenRdCount() == 0) {
            retAtsTrans.writeRespInfo("交易为空");
            retAtsTrans.writeRespCode("0");
        }
        retAtsTrans.writeEnd();
        return retAtsTrans;
    }

    /**
     * 集团不含成员单位
     * @param p_req7516
     * @return
     * @throws Exception
     */
    private RetAtsTrans d7516HisTrans_B(Req7516HisTrans p_req7516) throws Exception{
        RetAtsTrans retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
        retAtsTrans.writeStart();
        String tmpRespCode = "";
        String tmpRespInfo ="";
        try{
            //起始日期
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());
            //结束日期
            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());
            //明细按月查询，有些银行不支持跨月查询
            int tmpIntDateFrom = 0;
            int tmpIntDateTo = 0;
            while(tmpIntDateFrom<=tmpIntDateTo && StringHelper.isNullOrEmpty(tmpRespCode)){
                Calendar tmpClndrStepTo = Calendar.getInstance();
                tmpClndrStepTo.setTime(tmpCalendarFrom.getTime());
                //当是跨月查询时，先查询起始日期到月末日期记录，再查询月末后一天日期到结束日期记录
                if(DateHelper.compareMonth(tmpCalendarFrom,tmpCalendarTo)==-1){//起始日期月份小于结束日期月份，表示跨月
                    tmpClndrStepTo.set(Calendar.DAY_OF_MONTH,tmpClndrStepTo.getActualMaximum(Calendar.DAY_OF_MONTH));//获取月末日期
                }else{
                    tmpClndrStepTo.setTime(tmpCalendarTo.getTime());
                }
                int tmpNowReadStart = 1;//起始笔数
                int tmpNowReadNum = 0;//已查询笔数
                Map<String,Integer> tmpTotalNum = new HashMap<String, Integer>();
                while (tmpNowReadNum==0 || tmpNowReadNum<tmpTotalNum.get("recordCount")){
                    //开始拼接请求报文头
                    XmlTextWriter xmlTextWriter = new XmlTextWriter();
                    GDRC01Header gdrc01Header=new GDRC01Header();
                    gdrc01Header.TrsCode="B2EActTrsQry";
                    gdrc01Header.ERPJnlNo=p_req7516.reqHeader.transSeqID;
                    writeCommonHeader(xmlTextWriter,gdrc01Header);
                    xmlTextWriter.writeEndElement();
                    //开始拼接请求报文体
                    XElement body = new XElement("Body","");
                    body.addChild(new XElement("AcNo",p_req7516.actNum));//账号
                    body.addChild(new XElement("BeginDate",Format.Date8Format.format(tmpCalendarFrom.getTime())));//交易起始日期yyyyMMdd
                    body.addChild(new XElement("EndDate",Format.Date8Format.format(tmpClndrStepTo.getTime())));//交易终止日期yyyyMMdd
                    body.addChild(new XElement("BeginNo",tmpNowReadStart+""));//交易起始号码
                    body.addChild(new XElement("RecordNum",getBankConfig().getValueAsString("pageSize")));//查询条数
                    xmlTextWriter.writeXElement(body);
                    xmlTextWriter.writeEndDocument();
                    //发送请求报文
                    String[] resutlt = sendToBank(xmlTextWriter.toXmlString());

                    //测试
                    //resutlt[0]="";
                    //resutlt[1]="";
                    //WriteBankLogStep3(resutlt[1]);

                    //处理响应报文
                    if(resutlt[0].length()==0){
                        StringBuilder tmpSbMsg = new StringBuilder();
                        XmlTextReader tmpBkReader = loadBankRespXmlReader(resutlt[1].trim(),tmpSbMsg);
                        if(tmpBkReader!=null) {
                            String respCode = tmpBkReader.getFirstText("/Message/Head/IBSReturnCode");
                            String respInfo = tmpBkReader.getFirstText("/Message/Head/IBSReturnMsg");
                            //交易成功
                            if("000000".equals(respCode)){
                                String recordCount = tmpBkReader.getFirstText("/Message/Body/RecordCount");//获取页面记录条数
                                String totalCount = tmpBkReader.getFirstText("/Message/Body/TotalCount");//获取总记录数
                                if(tmpTotalNum.containsKey("recordCount")){
                                    if(tmpTotalNum.get("recordCount").intValue()!=Integer.valueOf(recordCount).intValue()){
                                        tmpRespCode ="-1";
                                        tmpRespInfo = "相同条件前后查出来的总数不一致";
                                        break;
                                    }
                                }else{
                                    if("0".equals(recordCount)){
                                        tmpRespCode ="0";
                                        tmpRespInfo = "该时间段的总明细条数为0";
                                        break;
                                    }
                                    tmpTotalNum.put("recordCount",Integer.valueOf(recordCount));//记录总条数
                                }
                                //取List/Map循环数据的值
                                int readCount =0;//设置遍历计数
                                while (tmpBkReader.read("/Message/Body/List/Map")){
                                    XElement readXElement = tmpBkReader.readedXElement;
                                    RetAtsTransDetail detail = new RetAtsTransDetail();
                                    detail.actArea=p_req7516.actArea;//账户区域
                                    detail.actNum=p_req7516.actNum;//银行账号
                                    detail.recAccNum=readXElement.getSingleTextNotNull("InAcNo").trim();//收方银行账号
                                    detail.recAccName=readXElement.getSingleTextNotNull("InAcName").trim();//收方账户名称
                                    detail.recAccBank=readXElement.getSingleTextNotNull("InBankName").trim();//收方银行
                                    detail.tranDate=DateHelper.convertD8toD10(readXElement.getSingleTextNotNull("TransactionDate").trim());//交易日期
                                    detail.tranTime=detail.tranDate+" 00:00:00";//交易时间
                                    detail.valueDate=detail.tranDate;//起息日，银行没有返回就用tranDate交易日期
                                    String amount=readXElement.getSingleTextNotNull("Amount").trim();
                                    if(amount.indexOf("+")>=0){//贷
                                        detail.cdFlag="2";
                                    }else if (amount.indexOf("-")>=0){//借
                                        detail.cdFlag="1";
                                    }else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "借贷标志( " + amount + ")无法识别，请与银行核对";
                                        break;
                                    }
                                    detail.tranAmt=amount.substring(1);//交易金额
                                    detail.accBal=readXElement.getSingleTextNotNull("Balance").trim();//账户余额
                                    detail.postTimestamp="";//时间戳，银行没有就空
                                    detail.billType="";//单据或票据类型，银行没有就空
                                    detail.billNum="";//单据或票据号码，银行没有就空
                                    String note = readXElement.getSingleTextNotNull("Digest").trim();
                                    detail.usage=note;//摘要
                                    detail.abstr=pickupAbstr(note);//对账码
                                    detail.payCode="";//支付码
                                    detail.comment=readXElement.getSingleTextNotNull("Describe").trim();//备注
                                    detail.askNumber="";//支付流水号
                                    detail.reqBatchNO="";//支付批号
                                    detail.cur="1";//币种
                                    detail.seqId="";//序列号
                                    detail.isCollection="";//是否现金池，银行没有就空
                                    detail.originator="";//柜员号
                                    detail.busType="";//新业务类型
                                    detail.urid="";//唯一明细号
                                    retAtsTrans.writeRetDetail(detail);
                                    readCount++;
                                }
                                //查询记录数和遍历数不一致
                                if(readCount!=Integer.valueOf(totalCount)){
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "统计明细有误";
                                    break;
                                }
                                tmpNowReadStart +=readCount;
                                tmpNowReadNum +=readCount;
                            }else {
                                tmpRespCode = "-1";
                                tmpRespInfo = respInfo;
                                break;
                            }
                        }else{
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpSbMsg.toString();
                            break;
                        }
                    }else{
                        tmpRespCode = "-1";
                        tmpRespInfo = resutlt[1];
                        break;
                    }
                }
                tmpCalendarFrom = tmpClndrStepTo;
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);//月末后一天日期
                tmpIntDateFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
                tmpIntDateTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            }
        }catch (Exception ex){
            tmpRespCode = "-1";
            tmpRespInfo = ex.getMessage();
            ex.printStackTrace();
            WriteBankLogLn("查询明细异常:"+ex);
        }
        if ("-1".equals(tmpRespCode)) {
            retAtsTrans = new RetAtsTrans(p_req7516.reqHeader);
            retAtsTrans.writeStart();//写返回ATS的统一头部信息
            retAtsTrans.writeRespCode(tmpRespCode);
            retAtsTrans.writeRespInfo(tmpRespInfo);
        }else if(retAtsTrans.getWrittenRdCount() == 0) {
            retAtsTrans.writeRespInfo("交易为空");
            retAtsTrans.writeRespCode("0");
        }
        retAtsTrans.writeEnd();
        return retAtsTrans;
    }


    /**
     * 今日明细
     * @param p_req7515
     * @return
     * @throws Exception
     */
    @Override
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception{
        Req7516HisTrans p_req7516 = new Req7516HisTrans(p_req7515.reqHeader);
        p_req7516.actArea = p_req7515.actArea;
        p_req7516.actCur = p_req7515.actCur;
        p_req7516.actNum = p_req7515.actNum;
        //String date = Format.Date8Format.format(new Date());
        String date = addDate();
        p_req7516.dateFrom = date;
        p_req7516.dateTo = date;
        return d_7516_HisTrans(p_req7516);
    }

}
